package cn.yuanqiao.web.controller.cqbc;


import cn.hutool.core.util.ZipUtil;
import cn.yuanqiao.common.exception.ServiceException;
import cn.yuanqiao.common.core.controller.BaseController;
import cn.yuanqiao.common.core.domain.AjaxResult;
import cn.yuanqiao.common.core.page.TableDataInfo;
import cn.yuanqiao.common.annotation.Log;
import cn.yuanqiao.common.enums.BusinessType;
import cn.yuanqiao.common.service.RedisService;
import cn.yuanqiao.cqbc.danganback.domain.YQDaBak;
import cn.yuanqiao.cqbc.danganback.form.IdForm;
import cn.yuanqiao.cqbc.danganback.form.YQDaBackIdForm;
import cn.yuanqiao.cqbc.danganback.param.YQDaBackLogParam;
import cn.yuanqiao.cqbc.danganback.param.YQDataBaseParam;
import cn.yuanqiao.cqbc.danganback.service.YQDaBackService;
import cn.yuanqiao.common.core.context.ResponseUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@RequestMapping(value = "/cqbc/daback")
@RestController
@Api(tags = "档案备份")
public class YQDaBackController extends BaseController {

    @Autowired
    YQDaBackService daBackService;
    @Autowired
    RedisService redisService;

    @ApiOperation("查询备份列表")
    @PostMapping(value = "/getBackDaLists")
    public TableDataInfo getBackDaLists(@RequestBody YQDaBak param) {
       startPage();
        return getDataTable(daBackService.getBackDaLists(param));
    }

    @Log(title = "新增备份", businessType = BusinessType.INSERT)
    @ApiOperation("备份新增")
    @PostMapping(value = "/addBackItem")
    public AjaxResult addBackItem(@RequestBody YQDaBak form) {
        return toAjax(daBackService.addBackItem(form));
    }

    @ApiOperation("备份详情")
    @RequestMapping(value = "/detail", method = RequestMethod.POST)
    public AjaxResult detail(@RequestParam(value = "id") String id) {
        return AjaxResult.success(daBackService.getByBakId(id));
    }

    @ApiOperation("修改备份")
    @Log(title = "修改备份", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/editItem")
    public AjaxResult editItem(@RequestBody YQDaBak vo) {
        try {
            this.daBackService.updateById(vo);
        } catch (Exception ex) {
            return AjaxResult.error("修改失败！");
        }

        return AjaxResult.success();
    }

    @Log(title = "删除备份", businessType = BusinessType.DELETE)
    @ApiOperation("删除备份")
    @GetMapping(value = "/deleteBack")
    public AjaxResult deleteBack(@Param("bakId") Long bakId) {
        YQDaBak yqDaBackVo = new YQDaBak();
        yqDaBackVo.setBakId(bakId);
        return toAjax(daBackService.deleteBack(yqDaBackVo));
    }

    @ApiOperation("备份")
    @PostMapping (value = "/backDa")
    public AjaxResult backDa(@RequestBody YQDaBackIdForm form) {
        return daBackService.backDa(form);
    }


    /**
     * 预留个异步的返回接口,目前采用同步方式
     *
     * @param backId 备份Id文件
     * @return ResponseData
     */
    @PostMapping("/downloadBackFile")
    public void downloadBackFile(@RequestHeader String backId, HttpServletResponse response) {
        YQDaBak backItem = daBackService.getBackItem(Long.valueOf(backId));
        YQDaBackLogParam yqDaBackLogParam = new YQDaBackLogParam();
        yqDaBackLogParam.setBakId(Long.valueOf(backId));
        List<Map<String, Object>> backDaLogLists = daBackService.getBackDaLogLists(yqDaBackLogParam, "");
        String tempPath = redisService.getCacheObject("YQ_MNT") + "/TEMP";
        String hdCharsetZip = redisService.getCacheObject("YQ_CHARSET_ZIP");
        // TODO 下载功能
        String uuid = UUID.randomUUID().toString();
        File tempDir = new File(tempPath + "/" + uuid);
        tempDir.mkdirs();
        for (Map<String, Object> item : backDaLogLists) {
            String bakFile = String.valueOf(item.get("bakFile"));
            File file = new File(bakFile);
            if (!file.exists()) {
                continue;
            }
            InputStream input = null;
            OutputStream output = null;
            try {
                input = new FileInputStream(file);
                File fileOut = new File(tempPath + "/" + uuid + "/" + file.getName());
                output = new FileOutputStream(fileOut);
                byte[] buf = new byte[1024];
                int bytesRead;
                while ((bytesRead = input.read(buf)) > 0) {
                    output.write(buf, 0, bytesRead);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    input.close();
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        ZipUtil.zip(tempPath + "/" + uuid, tempPath + "/" + uuid + ".zip", Charset.forName(hdCharsetZip), false);

        System.out.println(111);
        System.out.println(222);
        try {
            fileDownload(response, tempPath, uuid + ".zip");
        } catch (Exception e) {
            e.printStackTrace();
        }
        response.setStatus(200);
        //return daBackService.downloadBackFile(backId,files);
    }

/*    public void exportZipFile (List<File> fileList, String zipName)  {
//        File target = new File(StorageTypes.IMAGE.getPath()+"/"+zipName);
        File target = new File(StorageTypes.ROOT.getPath()+"/"+zipName);
        try (ArchiveOutputStream o = new ZipArchiveOutputStream(target)) {
            for (File f : fileList) {
                ArchiveEntry entry = o.createArchiveEntry(f, f.getName());
                o.putArchiveEntry(entry);
                if (f.isFile()) {
                    try (InputStream i = Files.newInputStream(f.toPath())) {
                        IOUtils.copy(i, o);
                    }
                }
                o.closeArchiveEntry();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }*/

    @Log(title = "测试链接", businessType = BusinessType.OTHER)
    @ApiOperation("测试连接")
    @GetMapping("/checkConn")
    public AjaxResult checkConn(YQDataBaseParam param) {
        return daBackService.checkConn(param);
    }

    @ApiOperation("获取恢复列表")
    @PostMapping(value = "/getBackDaLogLists")
    public TableDataInfo getBackDaLogLists(@Validated YQDaBackLogParam param, String bakName) {
        startPage();
        return getDataTable(daBackService.getBackDaLogLists(param, bakName));
    }

    @Log(title = "恢复数据库", businessType = BusinessType.OTHER)
    @ApiOperation("恢复数据库")
    @PostMapping(value = "/recoveryData")
    public AjaxResult recoveryData(@RequestBody IdForm form) {
        return daBackService.recoveryData(form);
    }

    @RequestMapping(value = "/getBackDaLog")
    public TableDataInfo getBackDaLog(Long baklogId) {
        startPage();
        return getDataTable(daBackService.getBackDaLog(baklogId));
    }

    /**
     * @param response
     * @param filePath 文件完整路径(包括文件名和扩展名)
     * @param fileName 下载后看到的文件名
     * @return 文件名
     */
    private static void fileDownload(final HttpServletResponse response, String filePath, String fileName) throws Exception {
        byte[] bytes = toByteArray(filePath + File.separator + fileName);
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.reset();
        // 设置 CORS 响应头
        ResponseUtils.defaultResponse(response);
        response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
        response.addHeader("Content-Length", "" + bytes.length);
        response.setContentType("application/octet-stream;charset=UTF-8");
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        outputStream.write(bytes);
        outputStream.flush();
        outputStream.close();
        response.flushBuffer();
    }

    public static byte[] toByteArray(String filename) {
        File f = new File(filename);
        if (!f.exists()) {
            throw new ServiceException("文件不存在!");
        } else {
            FileChannel channel = null;
            FileInputStream fs = null;

            try {
                fs = new FileInputStream(f);
                channel = fs.getChannel();
                ByteBuffer byteBuffer = ByteBuffer.allocate((int)channel.size());

                while(channel.read(byteBuffer) > 0) {
                }

                byte[] var5 = byteBuffer.array();
                return var5;
            } catch (IOException var17) {
                throw new ServiceException("文件不存在!");
            } finally {
                try {
                    channel.close();
                } catch (IOException var16) {
                    throw new ServiceException("文件不存在!");
                }

                try {
                    fs.close();
                } catch (IOException var15) {
                    throw new ServiceException("文件不存在!");
                }
            }
        }
    }
}
